
package com.hlkj.pay.app.merchant.ext.impl.easypay;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.id.IdUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.framework.http.template.OkHttpTemplate;
import com.hlkj.pay.app.merchant.ext.ChannelMerchantProfitOrderExtPt;
import com.hlkj.pay.app.merchant.ext.MerchantExtConstant;
import com.hlkj.pay.app.merchant.ext.dto.profit.ChannelProfitOrderContext;
import com.hlkj.pay.app.merchant.ext.dto.profit.ChannelProfitOrderQueryContext;
import com.hlkj.pay.app.merchant.ext.impl.easypay.constant.EasyPayConstant;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.EasyPayConfig;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.EasypayAppChannelParams;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.req.*;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.EasePayCommonRes;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.EasyPayRespStateInfo;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.fund.FundResBody;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.fund.RespFundOrderInfo;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.fund.SeparateRespInfoList;
import com.hlkj.pay.app.merchant.ext.impl.easypay.dto.res.order.RefundOrderRspBody;
import com.hlkj.pay.app.merchant.ext.impl.easypay.handler.EasyPayMerchantAccessInfoHandler;
import com.hlkj.pay.app.merchant.ext.impl.easypay.utils.EasyPaySignUtil;
import com.hlkj.pay.common.MerchantResultCode;
import com.hlkj.pay.dto.order.PayOrderFundDto;
import com.hlkj.pay.dto.order.RefundOrderFundDto;
import com.hlkj.pay.enums.PayEnums;
import com.hlkj.pay.enums.PayOrderEnums;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAppChannelDO;
import com.hlkj.pay.infrastructure.model.order.OrderFundDetailDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelRequestDO;
import com.hlkj.pay.infrastructure.model.pay.PayWayDO;
import com.hlkj.pay.infrastructure.model.pay.ProviderChannelConfigDO;
import com.hlkj.pay.util.DateUtils;
import com.hlkj.pay.util.HttpRequestUtil;
import com.hlkj.pay.util.MerchantUtils;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import jodd.util.StringPool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2025/01/06 17:47
 */
@Slf4j
@Repository
@RequiredArgsConstructor
@Extension(bizId = MerchantExtConstant.CHANNEL_EASY_PAY)
public class EasyPayMerchantProfitOrderExtPt implements ChannelMerchantProfitOrderExtPt {

    private final OkHttpTemplate okHttpTemplate;

    private final EasyPayMerchantAccessInfoHandler easyPayMerchantAccessInfoHandler;

    @Value("${hlkj.domain}")
    private String domain;

    @Override
    public void submitOrderProfit(ChannelProfitOrderContext channelProfitOrderContext) {
        ProviderChannelConfigDO providerChannelConfigDO = channelProfitOrderContext.getProviderChannelConfig();
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(channelConfig, EasyPayConfig.class);
        PayOrderDO payOrderDO = channelProfitOrderContext.getPayOrderDO();
        log.info("submitOrderProfit 订单信息：{}",JSONUtil.toJsonStr(payOrderDO));
        PayWayDO payWayDO = channelProfitOrderContext.getPayWayDO();
        MerchantAppChannelDO merchantAppChannelDO = channelProfitOrderContext.getMerchantAppChannelDO();
        try {
            List<PayOrderFundDto> payOrderFundDtos = channelProfitOrderContext.getPayOrderFundDtoList();
            EasypayAppChannelParams easypayAppChannelParams = easyPayAppChannelParams(merchantAppChannelDO);
            log.info("submitOrderProfit easypayAppChannelParams：{}",JSONUtil.toJsonStr(easypayAppChannelParams));

            // BigDecimal sum = easyPayMerchantAccessInfoHandler.sum(payOrderFundDtos,true);
            // BigDecimal sepaFeeRatio = easyPayMerchantAccessInfoHandler.sum(payOrderFundDtos,false);
            // if (sepaFeeRatio == null) {
            //     sepaFeeRatio = new BigDecimal(0);
            // }
            // log.info("submitOrderProfit sum:{},sepaFeeRatio：{}",sum,sepaFeeRatio);
            // 没有达到条件补充一条
            // if (payOrderDO.getAmount().compareTo(sum) > 0) {
            //     BigDecimal subtract = payOrderDO.getAmount().subtract(sum);
            //     PayOrderFundDto oneAccount = payOrderFundDtos.get(0);
            //     PayOrderFundDto orderAccount = new PayOrderFundDto();
            //     orderAccount.setAmount(MerchantUtils.bigDecimalToString2(subtract));
            //     orderAccount.setAccountNo(easypayAppChannelParams.getCustomerNo());
            //     orderAccount.setDescription("多余部分分给自己");
            //     orderAccount.setPeriodType(oneAccount.getPeriodType());
            //     orderAccount.setSepaFeeRatio((100 - sepaFeeRatio.intValue()) + "");
            //     orderAccount.setBatchNo(oneAccount.getBatchNo());
            //     orderAccount.setBatchNoDetail(oneAccount.getBatchNo() + "_" + (payOrderFundDtos.size() + 1));
            //     // orderAccount.setOrgSerialNumber();
            //     if(new BigDecimal(orderAccount.getAmount()).compareTo(new BigDecimal(0)) > 0){
            //         payOrderFundDtos.add(orderAccount);
            //         channelProfitOrderContext.setAddPayOrderFund(orderAccount);
            //     }
            // }

            log.info("易生 订单分润 实际分润详情:{}", JsonUtils.toJsonString(payOrderFundDtos));
            Map<String, Object> params = new HashMap<>();
            ReqInfo reqInfo = new ReqInfo();
            reqInfo.setMchtCode(easypayAppChannelParams.getCustomerNo());
            PayInfo payInfo = payInfo(payOrderDO, payWayDO);
            FundReqOrderInfo fundReqOrderInfo = processFund(payOrderDO, payOrderFundDtos, easypayAppChannelParams);
            // 异步通知地址
            String notifyUrl = domain + MerchantExtConstant.MERCHANT_ORDER_DIVICE_CALLBACK_URL + payOrderDO.getChannelCode() +
                    StringPool.SLASH + payOrderDO.getProviderCode()+ StringPool.SLASH + payOrderFundDtos.get(0).getBatchNo();
            fundReqOrderInfo.setBackUrl(notifyUrl);
            params.put("reqInfo", reqInfo);
            params.put("reqOrderInfo", fundReqOrderInfo);
            params.put("payInfo", payInfo);
            EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, params);
            String requestBody = JsonUtils.toJsonString(easyPayReqDto);
            log.info("易生 订单分润 请求参数:{}", requestBody);
            String url = yqtDomain(channelProfitOrderContext.isTest()) + EasyPayConstant.FUND_ORDER_APPLY;
            PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
            channelProfitOrderContext.setPayChannelRequest(payChannelRequestDO);
            payChannelRequestDO.setResponse(payChannelRequestDO.getResponse());
            log.info("易生 订单分润 返回参数:{}", payChannelRequestDO.getResponse());
            EasePayCommonRes<FundResBody> easePayCommonRes = JsonUtils.parseObject(payChannelRequestDO.getResponse(), new TypeReference<>() {
            });
            channelProfitOrderContext.setPayChannelRequest(payChannelRequestDO);
            channelProfitOrderContext.setRequestUrl(url);
            List<OrderFundDetailDO> upPayOrderFundList = new ArrayList<>();
            if (!easePayCommonRes.success()) {
                channelProfitOrderContext.setRemark("易生订单分润请求失败,失败信息:" + easePayCommonRes.getRspHeader().getRspInfo());
                channelProfitOrderContext.setProcessStatus(false);
                return;
            }
            FundResBody rspBody = easePayCommonRes.getRspBody();
            if (!rspBody.getRespStateInfo().success()) {
                channelProfitOrderContext.setRemark("易生订单分润请求失败,失败信息:" + rspBody.getRespStateInfo().getRespDesc());
                channelProfitOrderContext.setProcessStatus(false);
                for (PayOrderFundDto payOrderFundDto : payOrderFundDtos) {
                    payOrderFundDto.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL);
                }
            }
            else {
                RespFundOrderInfo respOrderInfo = easePayCommonRes.getRspBody().getRespOrderInfo();
                if (respOrderInfo != null || !CollectionUtils.isEmpty(respOrderInfo.getSeparateRespInfoList())) {
                    Map<String, SeparateRespInfoList> collect = respOrderInfo.getSeparateRespInfoList().stream()
                            .collect(Collectors.toMap(separateRespInfoList -> separateRespInfoList.getSeparateTrade(), Function.identity()));
                    for (PayOrderFundDto payOrderFundDto : payOrderFundDtos) {
                        SeparateRespInfoList separateRespInfoList = collect.get(payOrderFundDto.getBatchNoDetail());
                        if (separateRespInfoList != null) {
                            if (!StringUtils.hasText(separateRespInfoList.getSepaStatus())) {
                                continue;
                            }
                            // 0 交易成功 支付成功
                            // X 交易失败 原因详见易生状态码
                            // 9 待处理 待处理
                            // 9 处理中 处理中
                            // R 分账已回退 分账已回退
                            switch (separateRespInfoList.getSepaStatus()) {
                                case "SUCCESS":
                                case "0":
                                    payOrderFundDto.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.SUCCESS);
                                    break;
                                case "FAIL":
                                    payOrderFundDto.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL);
                                    break;
                                default:
                                    payOrderFundDto.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FUNDING);
                            }
                            payOrderFundDto.setFailReason(separateRespInfoList.getSepaStatusDesc());
                        }
                        else {
                            payOrderFundDto.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FUNDING);
                        }
                    }
                }
            }
            // channelProfitOrderContext.setUpdatePayOrderFundList(upPayOrderFundList);
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生提交订单分润请求失败 message:{}", e.getMessage(), e);
            channelProfitOrderContext.setRemark("易生提交订单分润请求失败,失败信息:" + e.getMessage());
            channelProfitOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    @Override
    public void queryOrderProfit(ChannelProfitOrderQueryContext channelProfitOrderQueryContext) {
        ProviderChannelConfigDO providerChannelConfigDO = channelProfitOrderQueryContext.getProviderChannelConfig();
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(channelConfig, EasyPayConfig.class);
        PayOrderDO payOrderDO = channelProfitOrderQueryContext.getPayOrderDO();
        PayWayDO payWayDO = channelProfitOrderQueryContext.getPayWayDO();
        MerchantAppChannelDO merchantAppChannelDO = channelProfitOrderQueryContext.getMerchantAppChannelDO();
        try {
            List<OrderFundDetailDO> payOrderFundList = channelProfitOrderQueryContext.getPayOrderFunds();
            EasypayAppChannelParams easypayAppChannelParams = easyPayAppChannelParams(merchantAppChannelDO);
            Map<String, Object> params = new HashMap<>();
            ReqInfo reqInfo = new ReqInfo();
            reqInfo.setMchtCode(easypayAppChannelParams.getCustomerNo());
            PayInfo payInfo = payInfo(payOrderDO, payWayDO);
            FundReqOrderInfo separateInfo = new FundReqOrderInfo();
            separateInfo.setOriSeparateBatchTrace(payOrderFundList.get(0).getBatchNo());
            separateInfo.setOriTransDate(DateUtils.dateToString(payOrderFundList.get(0).getCreateTime(), DatePattern.PURE_DATE_PATTERN));
            params.put("reqInfo", reqInfo);
            params.put("reqOrderInfo", separateInfo);
            params.put("payInfo", payInfo);
            EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, params);
            String requestBody = JsonUtils.toJsonString(easyPayReqDto);
            log.info("易生 订单分润查询 请求参数:{}", requestBody);
            String url = yqtDomain(channelProfitOrderQueryContext.isTest()) + EasyPayConstant.FUND_ORDER_QUERY;
            PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
            payChannelRequestDO.setResponse(payChannelRequestDO.getResponse());
            log.info("易生 订单分润查询 返回参数:{}", payChannelRequestDO.getResponse());
            EasePayCommonRes<FundResBody> easePayCommonRes = JsonUtils.parseObject(payChannelRequestDO.getResponse(), new TypeReference<>() {
            });
            List<OrderFundDetailDO> upPayOrderFundList = new ArrayList<>();
            if (!easePayCommonRes.success()) {
                channelProfitOrderQueryContext.setRemark("易生订单分润查询请求失败,失败信息:" + easePayCommonRes.getRspHeader().getRspInfo());
                channelProfitOrderQueryContext.setProcessStatus(false);
                return;
            }
            FundResBody rspBody = easePayCommonRes.getRspBody();
            if (!rspBody.getRespStateInfo().success()) {
                channelProfitOrderQueryContext.setRemark("易生订单分润查询请求失败,失败信息:" + rspBody.getRespStateInfo().getRespDesc());
                channelProfitOrderQueryContext.setProcessStatus(false);
                return;
            }
            else {
                RespFundOrderInfo respOrderInfo = easePayCommonRes.getRspBody().getRespOrderInfo();
                if (respOrderInfo != null || !CollectionUtils.isEmpty(respOrderInfo.getSeparateRespInfoList())) {
                    Map<String, SeparateRespInfoList> collect = respOrderInfo.getSeparateRespInfoList().stream()
                            .collect(Collectors.toMap(separateRespInfoList -> separateRespInfoList.getSeparateTrade(), Function.identity()));
                    for (OrderFundDetailDO payOrderFundDO : payOrderFundList) {
                        OrderFundDetailDO orderFundDO = new OrderFundDetailDO();
                        SeparateRespInfoList separateRespInfoList = collect.get(payOrderFundDO.getBatchNoDetail());
                        orderFundDO.setId(payOrderFundDO.getId());
                        if (separateRespInfoList != null) {
                            if (!StringUtils.hasText(separateRespInfoList.getSepaStatus())) {
                                continue;
                            }
                            // 0 交易成功 支付成功
                            // X 交易失败 原因详见易生状态码
                            // 9 待处理 待处理
                            // 9 处理中 处理中
                            // R 分账已回退 分账已回退
                            switch (separateRespInfoList.getSepaStatus()) {
                                case "0":
                                case "R":
                                case "SUCCESS":
                                    orderFundDO.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.SUCCESS.getCode());
                                    break;
                                case "FAIL":
                                    orderFundDO.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL.getCode());
                                    break;
                                default:
                                    orderFundDO.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FUNDING.getCode());
                            }
                            orderFundDO.setFailReason(separateRespInfoList.getSepaStatusDesc());
                        }
                        else {
                            orderFundDO.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FUNDING.getCode());
                        }
                        upPayOrderFundList.add(orderFundDO);
                    }
                }
            }
            channelProfitOrderQueryContext.setPayOrderFunds(upPayOrderFundList);
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生 订单分润查询请求失败 message:{}", e.getMessage(), e);
            channelProfitOrderQueryContext.setRemark("易生 订单分润查询请求失败,失败信息:" + e.getMessage());
            channelProfitOrderQueryContext.setProcessStatus(Boolean.FALSE);
        }
    }

    @Override
    public void submitRefundOrderProfit(ChannelProfitOrderContext channelProfitOrderContext) {
        ProviderChannelConfigDO providerChannelConfigDO = channelProfitOrderContext.getProviderChannelConfig();
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(channelConfig, EasyPayConfig.class);
        PayOrderDO payOrderDO = channelProfitOrderContext.getPayOrderDO();
        PayWayDO payWayDO = channelProfitOrderContext.getPayWayDO();
        MerchantAppChannelDO merchantAppChannelDO = channelProfitOrderContext.getMerchantAppChannelDO();
        try {
            // List<OrderFundDetailDO> payOrderFundList =
            // channelProfitOrderContext.getRefundOrderFundList();
            EasypayAppChannelParams easypayAppChannelParams = easyPayAppChannelParams(merchantAppChannelDO);
            Map<String, Object> params = new HashMap<>();
            ReqInfo reqInfo = new ReqInfo();
            reqInfo.setMchtCode(easypayAppChannelParams.getCustomerNo());
            PayInfo payInfo = payInfo(payOrderDO, payWayDO);
            params.put("reqInfo", reqInfo);
            params.put("payInfo", payInfo);
            String url = yqtDomain(channelProfitOrderContext.isTest()) + EasyPayConstant.FUND_ORDER_REFUND;
            for (RefundOrderFundDto refundOrderFundDto : channelProfitOrderContext.getRefundOrderFundDtoList()) {
                FundReqRefundOrderInfo fundReqOrderInfo = new FundReqRefundOrderInfo();
                //商户订单号
                fundReqOrderInfo.setOrgTrace(refundOrderFundDto.getBatchNoDetail());
                //原分账子单流水号
                fundReqOrderInfo.setOriSeparateTrade(refundOrderFundDto.getOrgBatchNoDetail());
                //原分账批次流水
                fundReqOrderInfo.setOriSeparateBatchTrace(refundOrderFundDto.getOrgBatchNo());
                fundReqOrderInfo.setOriTransDate(DateUtils.dateToString(refundOrderFundDto.getCreateTime(), DatePattern.PURE_DATE_PATTERN));
                fundReqOrderInfo.setRefundAmount(MerchantUtils.YuanToFen(new BigDecimal(refundOrderFundDto.getAmount())));
                params.put("reqOrderInfo", fundReqOrderInfo);
                EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, params);
                String requestBody = JsonUtils.toJsonString(easyPayReqDto);
                log.info("易生 退款订单分润 请求参数:{}", requestBody);
                PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
                channelProfitOrderContext.setPayChannelRequest(payChannelRequestDO);
                payChannelRequestDO.setResponse(payChannelRequestDO.getResponse());
                log.info("易生 退款订单分润 返回参数:{}", payChannelRequestDO.getResponse());
                EasePayCommonRes<FundResBody> easePayCommonRes = JsonUtils.parseObject(payChannelRequestDO.getResponse(), new TypeReference<>() {
                });
                channelProfitOrderContext.setPayChannelRequest(payChannelRequestDO);
                channelProfitOrderContext.setRequestUrl(url);
                if (!easePayCommonRes.success()) {
                    refundOrderFundDto.setFailReason("易生退款订单分润请求失败,失败信息:" + easePayCommonRes.getRspHeader().getRspInfo());
                    refundOrderFundDto.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL);
                    continue;
                }
                FundResBody rspBody = easePayCommonRes.getRspBody();
                if (!rspBody.getRespStateInfo().success()) {
                    refundOrderFundDto.setFailReason("易生退款订单分润请求失败,失败信息:" + rspBody.getRespStateInfo().getRespDesc());
                    refundOrderFundDto.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL);
                    return;
                }
                else {
                    RespFundOrderInfo respOrderInfo = easePayCommonRes.getRspBody().getRespOrderInfo();
                    EasyPayRespStateInfo easyPayRespStateInfo = rspBody.getRespStateInfo();
                    switch (easyPayRespStateInfo.getTransState()) {
                        case "0":
                        case "R":
                            refundOrderFundDto.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.REFUND);
                            break;
                        default:
                            refundOrderFundDto.setFailReason(easyPayRespStateInfo.getRespDesc());
                            refundOrderFundDto.setFailReason(easyPayRespStateInfo.getTransStatusDesc());
                            break;
                    }
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生提交退款订单分润请求失败 message:{}", e.getMessage(), e);
            channelProfitOrderContext.setRemark("易生提交退款订单分润请求失败,失败信息:" + e.getMessage());
            channelProfitOrderContext.setProcessStatus(Boolean.FALSE);
        }
    }

    @Override
    public void queryRefundOrderProfit(ChannelProfitOrderQueryContext channelProfitOrderQueryContext) {
        ProviderChannelConfigDO providerChannelConfigDO = channelProfitOrderQueryContext.getProviderChannelConfig();
        String channelConfig = providerChannelConfigDO.getParamsConfig();
        // 配置转换
        EasyPayConfig easyPayConfig = JsonUtils.parseObject(channelConfig, EasyPayConfig.class);
        PayOrderDO payOrderDO = channelProfitOrderQueryContext.getPayOrderDO();
        PayWayDO payWayDO = channelProfitOrderQueryContext.getPayWayDO();
        MerchantAppChannelDO merchantAppChannelDO = channelProfitOrderQueryContext.getMerchantAppChannelDO();
        try {
            EasypayAppChannelParams easypayAppChannelParams = easyPayAppChannelParams(merchantAppChannelDO);
            Map<String, Object> params = new HashMap<>();
            ReqInfo reqInfo = new ReqInfo();
            reqInfo.setMchtCode(easypayAppChannelParams.getCustomerNo());
            PayInfo payInfo = payInfo(payOrderDO, payWayDO);
            params.put("reqInfo", reqInfo);
            params.put("payInfo", payInfo);
            String url = yqtDomain(channelProfitOrderQueryContext.isTest()) + EasyPayConstant.TRADE_REFUND_QUERY;
            for (OrderFundDetailDO refundOrderFund : channelProfitOrderQueryContext.getRefundOrderFunds()) {

                Map<String, Object> reqOrderInfo = new HashMap<>();
                reqOrderInfo.put("orgTrace", IdUtils.getSnowflake().nextIdStr());
                reqOrderInfo.put("oriOrgTrace", refundOrderFund.getBatchNoDetail());
                reqOrderInfo.put("oriTransDate", DateUtils.dateToString(refundOrderFund.getCreateTime(), DatePattern.PURE_DATE_PATTERN));
                params.put("reqOrderInfo", reqOrderInfo);

                EasyPayReqDto easyPayReqDto = easyPayReqDto(easyPayConfig, params);
                String requestBody = JsonUtils.toJsonString(easyPayReqDto);
                log.info("易生 退款订单分润查询 请求参数:{}", requestBody);
                PayChannelRequestDO payChannelRequestDO = payChannelRequestDO(url, easyPayReqDto);
                payChannelRequestDO.setResponse(payChannelRequestDO.getResponse());
                log.info("易生 退款订单分润查询 返回参数:{}", payChannelRequestDO.getResponse());
                EasePayCommonRes<RefundOrderRspBody> easePayCommonRes = JsonUtils.parseObject(payChannelRequestDO.getResponse(), new TypeReference<>() {
                });
                if (!easePayCommonRes.success()) {
                    refundOrderFund.setFailReason("易生 退款订单分润查询请求失败,失败信息:" + easePayCommonRes.getRspHeader().getRspInfo());
                    refundOrderFund.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL.getCode());
                    continue;
                }
                RefundOrderRspBody rspBody = easePayCommonRes.getRspBody();
                EasyPayRespStateInfo easyPayRespStateInfo = rspBody.getRespStateInfo();
                if (!easyPayRespStateInfo.success()) {
                    refundOrderFund.setFailReason("易生 退款订单分润查询请求失败,失败信息:" + easyPayRespStateInfo.getRespDesc());
                    refundOrderFund.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL.getCode());
                    continue;
                }
                switch (easyPayRespStateInfo.getTransState()) {
                    case "0":
                    case "R":
                        refundOrderFund.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.SUCCESS.getCode());
                        break;
                    case "A":
                    case "9":
                    case "C":
                    case "X":
                        refundOrderFund.setFundStatus(PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL.getCode());
                        refundOrderFund.setFailReason(easyPayRespStateInfo.getRespDesc());
                        break;
                    default:
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("易生退款订单查询请求失败 message:{}", e.getMessage(), e);
            channelProfitOrderQueryContext.setRemark("易生退款订单查询请求失败,失败信息" + e.getMessage());
            channelProfitOrderQueryContext.setProcessStatus(Boolean.FALSE);
        }
    }

    @Override
    public void finishAcctOrder(ChannelProfitOrderContext channelProfitOrderContext) {
        channelProfitOrderContext.setProcessStatus(Boolean.FALSE);
        channelProfitOrderContext.setRemark("易生分账不支持完结");
    }

    @Override
    public CommonResult<String> acctStatusParse(HttpServletRequest request, ChannelProfitOrderContext channelProfitOrderContext) {

        CommonResult<String> commonResult = CommonResult.success();
        try{
            // 获取回调参数
            String result = HttpRequestUtil.requestBodyParams(request);
            EasyPayAcctCallback acctCallback = JSONUtil.toBean(result,EasyPayAcctCallback.class);
            FundResBody fundResBody = acctCallback.getReqBody();
            log.info("easypay acctStatusParse text:{}", JSONUtil.toJsonStr(fundResBody));

            // 分账详情
            List<OrderFundDetailDO> orderFundDetailList = channelProfitOrderContext.getOrderFundDetailDOList();
            PayOrderEnums.PAY_ORDER_FUND_STATUS payOrderFundStatus = null;
            String failMsg = null;
            EasyPayRespStateInfo easyPayRespStateInfo = fundResBody.getRespStateInfo();
            switch (easyPayRespStateInfo.getTransState()) {
                case "0":
                case "R":
                    payOrderFundStatus = PayOrderEnums.PAY_ORDER_FUND_STATUS.SUCCESS;
                    break;
                case "A":
                case "9":
                case "C":
                case "X":
                    payOrderFundStatus = PayOrderEnums.PAY_ORDER_FUND_STATUS.FAIL;
                    failMsg = easyPayRespStateInfo.getRespDesc();
                    break;
            }

            channelProfitOrderContext.setPayOrderFundStatus(payOrderFundStatus);
            for(OrderFundDetailDO fundDetailDO:orderFundDetailList){
                fundDetailDO.setFundStatus(payOrderFundStatus.getCode());
                fundDetailDO.setDetailId(fundResBody.getRespOrderInfo().getProductTrace());
                if(StrUtil.isNotEmpty(failMsg)){
                    fundDetailDO.setFailReason(failMsg);
                }
            }

        }catch (Exception e){
            commonResult.setCode(MerchantResultCode.MERCHANT_CHANNEL_CALLBACK_SIGN_ERROR.getCode());
        }


        return commonResult;
    }

    @Override
    public void settleConfirm(ChannelProfitOrderContext channelProfitOrderContext) {

    }

    FundReqOrderInfo processFund(PayOrderDO payOrderDO, List<PayOrderFundDto> accounts, EasypayAppChannelParams easypayAppChannelParams) {
        FundReqOrderInfo separateInfo = new FundReqOrderInfo();
        separateInfo.setOriOrgTrace(payOrderDO.getPayOrderNo());
        separateInfo.setOriTransDate(DateUtils.dateToString(payOrderDO.getCreateTime(), DatePattern.PURE_DATE_PATTERN));
        separateInfo.setSeparateBatchTrace(accounts.get(0).getBatchNo());
        List<SeparateOrderDetailList> separateOrderDetails = new ArrayList<>();
        Integer amount = MerchantUtils.YuanToFen(payOrderDO.getAmount());
        accounts.stream().forEach(account -> {
            SeparateOrderDetailList separateOrderDetailList = new SeparateOrderDetailList();
            // 易生分账DO开关
            if(account.getPeriodType() != null && account.getPeriodType() == 1){
                separateOrderDetailList.setIsD0("1");
            }
            separateOrderDetailList.setReceiveMchtCode(account.getAccountNo());
            separateOrderDetailList.setSeparateTrade(account.getBatchNoDetail());
            separateOrderDetailList.setSepaTransAmount(MerchantUtils.YuanToFen(new BigDecimal(account.getAmount())));
            if(StrUtil.isNotEmpty(account.getSepaFeeRatio())){
                separateOrderDetailList
                        .setSepaFeeAmount(new BigDecimal(account.getSepaFeeRatio()).divide(new BigDecimal(100)).multiply(new BigDecimal(account.getAmount())).setScale(2).intValue());
            }else{
                separateOrderDetailList.setSepaFeeAmount(0);
            }
            separateOrderDetailList.setSubject(account.getDescription());
            separateOrderDetails.add(separateOrderDetailList);
        });
        separateInfo.setSeparateOrderDetailList(separateOrderDetails);
        separateInfo.setTransSumAmt(amount);
        separateInfo.setTransSumCount(separateOrderDetails.size());
        separateInfo.setSeparateOrderDetailList(separateOrderDetails);
        separateInfo.setTransSumAmt(separateOrderDetails.stream().mapToInt(separateOrderDetailList -> separateOrderDetailList.getSepaTransAmount()).sum());
        return separateInfo;
    }

    EasyPayReqDto easyPayReqDto(EasyPayConfig easyPayConfig, Map<String, Object> params) throws Exception {
        EasyPayReqDto easyPayReqDto = new EasyPayReqDto();
        easyPayReqDto.setReqHeader(new EasyPayReqHeader(easyPayConfig.getReqId(), DateUtils.getDateString(DatePattern.PURE_DATETIME_PATTERN)));
        easyPayReqDto.setReqBody(params);
        easyPayReqDto.setReqSign(EasyPaySignUtil.sign(easyPayReqDto, easyPayConfig.getRsaPrivateKey()));
        return easyPayReqDto;
    }

    public EasypayAppChannelParams easyPayAppChannelParams(MerchantAppChannelDO merchantAppChannelDO) {
        return JsonUtils.parseObject(merchantAppChannelDO.getAppConfigJson(), EasypayAppChannelParams.class);
    }

    PayInfo payInfo(PayOrderDO payOrderDO, PayWayDO payWayDO) {
        PayInfo payInfo = new PayInfo();
        payInfo.setTransDate(DateUtils.dateToString(System.currentTimeMillis(), DatePattern.PURE_DATE_PATTERN));
        payInfo.setPayType(getPayType(payWayDO));
        return payInfo;
    }

    private String getPayType(PayWayDO payWayDO) {
        PayEnums.SCENE_PAY_TYPE scenePayType = PayEnums.SCENE_PAY_TYPE.from(payWayDO.getSubType());
        PayEnums.PAY_TYPE payType = PayEnums.PAY_TYPE.fromByCode(payWayDO.getType());
        if (Objects.isNull(scenePayType) || Objects.isNull(payType))
            return "";
        switch (payType) {
            case ALIPAY:
                switch (scenePayType) {
                    case QR:
                        return "AliPayNative";
                }
            case UNION_APY:
                switch (scenePayType) {
                    case QR:
                        return "UnionPayNative";
                }
        }
        return "";
    }

    PayChannelRequestDO payChannelRequestDO(String url, Object params) throws Exception {
        PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
        payChannelRequestDO.setRequestUrl(url);
        String requestBody = JsonUtils.toJsonString(params);
        payChannelRequestDO.setRequestParams(requestBody);
        String post = okHttpTemplate.post(url, requestBody, null);
        payChannelRequestDO.setResponse(post);
        return payChannelRequestDO;
    }

    public String yqtDomain(boolean test) {
        return test ? EasyPayConstant.PAY_ORDER_DOMAIN_TEST : EasyPayConstant.PAY_ORDER_DOMAIN_PROD;
    }

}
